﻿#pragma once
#include <memory>
#include <functional>
#include <array>

#ifdef _WIN32
#include "wepoll.h"
#endif

#include "time_value.h"
#include "as_socket.h"

//Ð­³Ì
#include "as_promise.h"


namespace as
{
	namespace net
	{
		class EpollWatch;
		class Channel
		{
		public:
			enum
			{
				E_CO_READ = 0,
				E_CO_WRITE = 1,
				E_CO_CLOSE = 2,
				E_CO_ERROR = 3,
				E_CO_MAX,
			};

			typedef std::function<void()> EventCb;
			typedef std::function<int(TimeValue&)> EventReadCb;
			Channel(std::shared_ptr<EpollWatch> &ep, socket_fd fd);
			Channel(std::shared_ptr<EpollWatch> &ep, std::shared_ptr<as::net::Socket> &socket);
			~Channel();
			void HandleEvent(TimeValue &t);

			void SetEvents(int evs);
			int GetEvents();

			void SetType(int type);
			int GetType();

			socket_fd GetFd();
			std::shared_ptr<as::net::Socket>& GetSocket();

			void EnableReadAndWriteFlag();
			void EnableReadFlag();
			void DisableReadFlag();

			void EnableWriteFlag();
			void DisableWriteFlag();
			bool IsWriteFlag();
			bool IsReadFlag();

			bool HasFlag();

			void ClearFlag();
			void RemoveLoop();
			void Update();

			void SetReadCoHandle(as::co::coroutine_handle handle);
			void SetWriteCoHandle(as::co::coroutine_handle handle);
			void SetCloseCoHandle(as::co::coroutine_handle handle);
			void SetErrorCoHandle(as::co::coroutine_handle handle);
			void CoCallCallback(int co_type);
			void ClearCoHandle(int co_type);
			void ClearAllCoHandle();
		public:
			void SetReadCallback(EventReadCb cb);
			void SetWriteCallback(EventCb cb);
			void SetErrorCallback(EventCb cb);
			void SetCloseCallback(EventCb cb);
		private:
			std::array<as::co::coroutine_handle, E_CO_MAX> co_handles_;
			std::weak_ptr<EpollWatch> ep_watch_;
			std::shared_ptr<Socket> socket_;
			int events_ = 0;
			int type_ = -1;
			EventReadCb read_cb_;
			EventCb write_cb_;
			EventCb err_cb_;
			EventCb close_cb_;
		};







	}
}






